package com.qingcloud.fexecutor.service;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.db.ds.simple.SimpleDataSource;
import cn.hutool.db.nosql.redis.RedisDS;
import cn.hutool.setting.Setting;
import com.qingcloud.fexecutor.base.executor.DataSourceExecutor;
import com.qingcloud.fexecutor.base.pojo.WebPageDataParam;
import com.qingcloud.fexecutor.mapper.WebPubAppMapper;
import com.qingcloud.fexecutor.mapper.WebPubPageResourceMapper;
import com.qingcloud.fexecutor.model.AppDataSource;
import com.qingcloud.fexecutor.model.WebPubApp;
import com.qingcloud.fexecutor.model.WebPubPageResource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Objects;

@Service
@Slf4j
public class WebPageDataService {

    @Resource
    private AppDataSourceService appDataSourceService;

    @Resource
    private WebPubAppMapper webPubAppMapper;

    @Resource
    private WebPubPageResourceMapper webPubPageResourceMapper;

    //数据源缓存
    TimedCache<String, DataSource> pageDataSourceCache = CacheUtil.newTimedCache(3600 * 1000);

    //Jedis缓存
    TimedCache<String, Jedis> pageJedisCache = CacheUtil.newTimedCache(3600 * 1000);

    /**
     * 获取页面的数据源
     */
    private DataSource getDataSource(int pageId, String resourceCode, Integer viewType) {
        Integer appId;
        String realCode;
        WebPubPageResource pageResource = webPubPageResourceMapper.selectOne(new WebPubPageResource().setPageId(pageId).setResourceCode(resourceCode));
        WebPubApp webPubApp = webPubAppMapper.selectByPrimaryKey(pageResource.getAppId());
        appId = webPubApp.getDevAppId();
        realCode = pageResource.getRealCode();
        //查询页面信息
        DataSource dataSource = pageDataSourceCache.get(realCode);
        if (Objects.isNull(dataSource)) {
            AppDataSource database = appDataSourceService.findUseInfo(appId, realCode);
            dataSource = new SimpleDataSource(database.getJdbcUrl(), database.getUsername(), database.getPassword());
            pageDataSourceCache.put(resourceCode, dataSource);
        }
        return dataSource;
    }

    private Jedis getJedis(int pageId, String resourceCode, int viewType) {
        Integer appId;
        String realCode;
        WebPubPageResource pageResource = webPubPageResourceMapper.selectOne(new WebPubPageResource().setPageId(pageId).setResourceCode(resourceCode));
        WebPubApp webPubApp = webPubAppMapper.selectByPrimaryKey(pageResource.getAppId());
        appId = webPubApp.getDevAppId();
        realCode = pageResource.getRealCode();
        //查询页面信息
        Jedis jedis = pageJedisCache.get(realCode);
        if (Objects.isNull(jedis)) {
            AppDataSource appDataSource = appDataSourceService.findUseInfo(appId, realCode);
            Setting setting = new Setting();
            setting.put("host", appDataSource.getIp());
            setting.put("port", String.valueOf(appDataSource.getPort()));
            setting.put("password", appDataSource.getPassword());
            setting.put("database", appDataSource.getCatalog());
            RedisDS redisDS = RedisDS.create(setting, null);
            jedis = redisDS.getJedis();
            pageJedisCache.put(resourceCode, jedis);
        }
        return jedis;
    }

    /**
     * redis指令执行
     */
    public Object redisExecute(WebPageDataParam.PageParam pageParam) {
        Jedis jedis = this.getJedis(pageParam.getPageId(), pageParam.getResourceCode(), pageParam.getViewType());
        return DataSourceExecutor.redisExecute(pageParam, jedis);
    }

    /**
     * sql分页查询数据
     */
    public Object sqlExecute(Integer pageId, String resourceCode, Integer page, Integer pageSize, String json, String sql, Integer viewType) throws Exception {
        //获取数据源
        DataSource dataSource = this.getDataSource(pageId, resourceCode, viewType);
        return DataSourceExecutor.sqlExecute(page, pageSize, json, sql, dataSource);
    }

}
